home *** CD-ROM | disk | FTP | other *** search
- /************************************************************************
- * *
- * MacWriteExport.c *
- * *
- * Translator for writing a MacWrite file with XTND 1.3. *
- * *
- * Copyright © 1989,90 Claris Corporation *
- * All Rights Reserved *
- * *
- * Author: Richard Scorer *
- * Date: 13 April, 1988 *
- * *
- ************************************************************************/
-
- #include <Resources.h>
- #include <ToolUtils.h>
- #include <StandardFile.h>
- #include <Memory.h>
- #include <Printing.h>
- enum { FALSE,TRUE };
-
- #ifndef THINK_C
- #include "CodeA5Globals.h"
- #endif
-
- #include ":::XTND Headers:XTNDCIncludes:XTNDTextTranslator.h" /* XTND Export defs */
-
- #include "MacWriteExport.h" /* MW 5.0 Export specifics */
- #include "MacWrite.h" /* MW 5.0 specifics */
-
-
- /*------------------------- Useful Constants ---------------------------*/
-
- #define MWFontSizes 6
- #define MWPageHeight 730 /* height of MacWrite page */
- #define MaxHFParas 8 /* max # of paragraphs allowed in a header or footer */
- #define StyleMask 0x007f /* mask for MoonRaker styles */
- /* #define NULL 0L */
-
- #define ISLINECHAR(ch) (ch <= returnChar && (ch >= newColumn || ch == hardReturn || ch == mergeBreak))
-
- typedef struct dummy
- {
- short x[5];
- } dummy;
-
-
- /*-------------------------Global Variables-----------------------------*/
-
- static ExportParmBlkPtr gExportPBPtr;
- static MacWriteHdrHandle MWHeader;
-
- static long gCount;
- static Fixed gOldFmt[numParaFmts];
- static TabSpec gOldTab[10];
- static short gOldJust;
- static Boolean gFirstTime, gNewParagraph, gFirstStyle;
-
- static ParagraphHandle gParaData;
- static FormatHandle gFormatRun;
- static LineHandle gLineData;
- static long gParaLength, gParaStart;
- static short gNumParas, gNumFormats, gTextLength, gPHeight, gRealParas;
- static char MWSizes[MWFontSizes] = {9, 10, 12, 14, 18, 24};
- static short gColumnWidth;
-
-
- /*-------------------------Function prototypes--------------------------*/
-
- void main(ExportParmBlkPtr exportParamPtr);
- static void ExportMacWrite(ExportParmBlkPtr exportParamPtr);
- static short WriteResources(void);
- static short InitAll(void);
- static short InitStory(void);
- static Boolean ChangeParagraph(void);
- static short InsertParagraph(void);
- static short WritePict(void);
- static short WritePageBreak(void);
- static short InsertRuler(void);
- static short FindFontSize(short);
- static short WriteParagraph(void);
- static short WriteCR(void);
- static short LastParagraph(void);
- static short CloseStory(void);
- static short TidyUp(void);
-
-
- /*----------------------------------------------------------------------*/
- /* */
- /* main This is the main routine and the only entry point for the */
- /* the translator. */
- /* NOTE: This translator uses globals that are used from the first to */
- /* last call. Therefore, the global data storage cannot be deallocated */
- /* when the translator receives the EXPORT_CLOSE_ALL directive. */
- /* Instead, it must deallocate its global storage when it receives the */
- /* EXPORT_WRITE_RESOURCES directive. If an exception occurs, causing */
- /* the application to abort the translation, the translator will never */
- /* receive the EXPORT_WRITE_RESOURCES directive and its global storage */
- /* will remain in the heap as useless garbage. Note to this note: this */
- /* note does NOT apply if you are using Think C’s A4-based globals. */
- /* */
- /*----------------------------------------------------------------------*/
- void main(exportParamPtr)
- ExportParmBlkPtr exportParamPtr;
- {
- #ifdef THINK_C
- asm {
- move.l a4,-(sp)
- move.l a0,a4 ; Sets up the globals for this CODE
- }
- #else
- long savedA5;
-
- if (exportParamPtr->directive == exportInitAll) {
- exportParamPtr->globalHandle = NewHandle(0L);
- MakeA5World(exportParamPtr->globalHandle);
- }
- savedA5 = SetA5World(exportParamPtr->globalHandle);
- #endif
-
- ExportMacWrite(exportParamPtr);
-
- #ifdef THINK_C
- asm {
- move.l (sp)+,a4
- }
- #else
- RestoreA5World(savedA5, exportParamPtr->globalHandle);
- if (exportParamPtr->directive == exportWriteResources) {
- DisposeA5World(exportParamPtr->globalHandle);
- exportParamPtr->globalHandle = NULL;
- }
- #endif
- }
-
-
- /*----------------------------------------------------------------------*/
- /* */
- /* ExportMacWrite dispatches the call to the appropriate routine */
- /* depending on the Directive. */
- /* */
- /*----------------------------------------------------------------------*/
- void ExportMacWrite(register ExportParmBlkPtr exportParamPtr)
- {
- gExportPBPtr = exportParamPtr; /* Save the param block pointer in a global */
-
- switch (exportParamPtr->directive) {
- case exportInitAll: /* Initialize the translator. This must be */
- InitAll(); /* the first call to the translator. */
- break;
-
- case exportOpenRightHeader: /* Initialize a story. */
- case exportOpenHeader: /* It could be any of these types */
- case exportOpenRightFooter:
- case exportOpenFooter:
- case exportOpenMain:
- exportParamPtr->directive = exportAcknowledge;
- InitStory();
- break;
-
- case exportOpenLeftHeader:
- /* Only accept left headers if there are no right headers */
- if (!(exportParamPtr->headerStatus & RightPage)) {
- exportParamPtr->directive = exportAcknowledge;
- InitStory();
- }
- break;
-
- case exportOpenLeftFooter:
- /* Only accept left footers if there are no right footers */
- if (!(exportParamPtr->footerStatus & RightPage)) {
- exportParamPtr->directive = exportAcknowledge;
- InitStory();
- }
- break;
-
- case exportWriteText: /* Write the next text run to the file. */
- WriteParagraph();
- break;
-
- case exportCloseRightHeader: /* Close any story when finished */
- case exportCloseLeftHeader: /* with it. */
- case exportCloseHeader:
- case exportCloseRightFooter:
- case exportCloseLeftFooter:
- case exportCloseFooter:
- case exportCloseMain:
- CloseStory();
- break;
-
- case exportCloseAll: /* Do required clean up here */
- TidyUp();
- break;
-
- case exportWriteResources:
- WriteResources();
- break;
-
- default:
- break;
- }
- } /* ExportMacWrite */
-
-
- /*----------------------------------------------------------------------*/
- /* */
- /* WriteResources writes certain resources required by MacWrite 5.0 */
- /* */
- /* We need to write: */
- /* 1. International resource */
- /* 2. Compression string (even though we don't use it, MW needs it) */
- /* 3. List of fonts. (not needed) */
- /* */
- /*----------------------------------------------------------------------*/
- static short WriteResources()
- {
- register Handle TheData;
- register short intl;
- short theID;
- ResType theType;
- register Str255 theName;
-
- *(gExportPBPtr->result) = noErr;
-
- UseResFile(*(gExportPBPtr->refNum));
- for (intl = 0; intl < 2; intl++) {
- TheData = GetResource('INTL', intl);
- DetachResource(TheData);
-
- AddResource(TheData, 'INTL', intl, (StringPtr)"\p");
- if (*(gExportPBPtr->result) = ResError()) return(*(gExportPBPtr->result));
- }
- TheData = GetResource('STR ', 700); /* Compression String */
- GetResInfo(TheData, &theID, &theType, theName);
- DetachResource(TheData);
-
- AddResource(TheData, 'STR ', 700, theName);
- if (*(gExportPBPtr->result) = ResError()) return(*(gExportPBPtr->result));
-
- CloseResFile(*(gExportPBPtr->refNum));
-
- return(noErr); /* To indicate we handled the resources */
- } /* WriteResources */
-
-
- /*----------------------------------------------------------------------*/
- /* */
- /* InitAll sets up storage for exporting. */
- /* */
- /*----------------------------------------------------------------------*/
- static short InitAll()
- {
- register short WindowType;
- LineHeightArray LHA;
- RulerParagraph TheRuler;
- InfoStruct Info[2];
- dummy para;
-
- /* Set up my globals et al */
- /* Write out the "blank" header for MacWrite files */
-
- gCount = sizeof(MacWriteHeader);
- MWHeader = (MacWriteHdrHandle)NewHandle(gCount);
- if (*(gExportPBPtr->result) = MemError()) return(*(gExportPBPtr->result));
-
- (**MWHeader).versionNo = 6;
- (**MWHeader).headerPars = 2;
- (**MWHeader).footerPars = 2;
- (**MWHeader).titlePage = (gExportPBPtr->titlePage ? 0xFF : 0);
- (**MWHeader).scrapDisplay = 0;
- (**MWHeader).footerDisplay = (gExportPBPtr->footerStatus == kNone ? 0 : 0xFF);
- (**MWHeader).headerDisplay = (gExportPBPtr->headerStatus == kNone ? 0 : 0xFF);
- (**MWHeader).rulersHidden = 0xFF; /* MUST BE TRUE!!! or page, date and time are wrong */
- (**MWHeader).activeDoc = 2; /* Tell MacWrite that document must be recalced */
- (**MWHeader).startPageNum = gExportPBPtr->startPageNum;
-
- for (WindowType = AFooter; WindowType <= TheMainDoc; WindowType++) {
- (**MWHeader).window[WindowType].selStartPar = 1;
- (**MWHeader).window[WindowType].selStartCh = 0;
- (**MWHeader).window[WindowType].selEndPar = 1;
- (**MWHeader).window[WindowType].selEndCh = 0;
- (**MWHeader).window[WindowType].vertOffSet = 0;
- (**MWHeader).window[WindowType].need2Redraw = 1;
- (**MWHeader).window[WindowType].infoAryLength = 0x20;
- (**MWHeader).window[WindowType].lineHeightAryLength = 0x6;
- (**MWHeader).window[WindowType].pageNumPos = 0xFFF2001E;
- (**MWHeader).window[WindowType].datePos = 0xFFF200C2;
- (**MWHeader).window[WindowType].timePos = WindowType == TheMainDoc ? 0xFFFFFFFF : 0xFFF20190;
- (**MWHeader).window[WindowType].ovalRedraw = 0xFF;
- (**MWHeader).window[WindowType].lastOval = 0xFF;
- (**MWHeader).window[WindowType].activeStyle = 0x0C00;
- (**MWHeader).window[WindowType].activeFont = 3;
- }
- gColumnWidth = (8 * 72 + 36); /* Document width = 8 inches * 72 pixels/inch + 1/2 inch */
-
- if (gExportPBPtr->printRecord) {
- PrOpen();
- if (!PrError()) {
- PrValidate(gExportPBPtr->printRecord);
- PrClose();
- gColumnWidth = (**gExportPBPtr->printRecord).rPaper.right - (**gExportPBPtr->printRecord).rPaper.left;
- }
- (**MWHeader).printRecord = **gExportPBPtr->printRecord;
- }
- gColumnWidth -= FixRound(gExportPBPtr->leftMargin + gExportPBPtr->rightMargin);
-
- if (*(gExportPBPtr->result) = FSWrite(*(gExportPBPtr->refNum), &gCount, *MWHeader))
- return(*(gExportPBPtr->result));
-
- /* Write out the dummy Footer paragraph & arrays if appropriate */
- TheRuler.leftMargin = 9;
- TheRuler.rightMargin = 0x1DD;
- TheRuler.justification = 0;
- TheRuler.numTabs = 1;
- TheRuler.lineSpacing = 0;
- TheRuler.lineIndent = 9;
- TheRuler.tabArray[0] = 0x144;
-
- para.x[0] = 0;
- para.x[1] = 6;
- para.x[2] = 0;
- para.x[3] = 0xC00;
- para.x[4] = 3;
-
- LHA.heightInfo[0] = 0;
- LHA.heightInfo[1] = 0;
- LHA.heightInfo[2] = 0;
- LHA.heightInfo[3] = 1;
- LHA.heightInfo[4] = 0x10;
- LHA.heightInfo[5] = 0;
-
- Info[0].paraHeight = 0;
- Info[1].paraHeight = 0x10;
- Info[0].paraPagePosn = Info[1].paraPagePosn = 0;
- Info[0].paraHndl = Info[1].paraHndl = 0L;
- Info[0].Status.justCode = Info[1].Status.justCode = 0;
- Info[0].paraFmt = 0;
- Info[1].paraFmt = 0x3301;
-
- for (WindowType = AFooter; WindowType < TheMainDoc; WindowType++) {
- if ((WindowType == AFooter && (**MWHeader).footerDisplay) ||
- (WindowType == AHeader && (**MWHeader).headerDisplay))
- continue;
-
- GetEOF(*(gExportPBPtr->refNum), &gParaStart);
- Info[0].Status.paraFilePosn = gParaStart;
-
- /* Make a ruler (0x22 bytes long) */
- gCount = Info[0].paraLen = sizeof(RulerParagraph);
-
- /* write out ruler record */
- if (*(gExportPBPtr->result) = FSWrite(*(gExportPBPtr->refNum), &gCount, &TheRuler))
- return(*(gExportPBPtr->result));
-
- GetEOF(*(gExportPBPtr->refNum), &gParaStart);
- Info[1].Status.paraFilePosn = gParaStart;
- gCount = Info[1].paraLen = 0xA;
-
- /* write out paragraph data */
- if (*(gExportPBPtr->result) = FSWrite(*(gExportPBPtr->refNum), &gCount, ¶))
- return(*(gExportPBPtr->result));
-
- gCount = 6;
- GetEOF(*(gExportPBPtr->refNum), &(**MWHeader).window[WindowType].lineHeightAryPos);
- if (*(gExportPBPtr->result) = FSWrite(*(gExportPBPtr->refNum), &gCount, &LHA))
- return(*(gExportPBPtr->result));
-
- gCount = 0x20;
- GetEOF(*(gExportPBPtr->refNum), &(**MWHeader).window[WindowType].infoAryPos);
- if (*(gExportPBPtr->result) = FSWrite(*(gExportPBPtr->refNum), &gCount, &Info[0]))
- return(*(gExportPBPtr->result));
- }
- return(noErr);
- } /* InitAll */
-
-
- /*----------------------------------------------------------------------*/
- /* */
- /* InitStory sets up a story. This consists of setting up required */
- /* handles and file info. */
- /* */
- /*----------------------------------------------------------------------*/
- static short InitStory()
- {
- GetEOF(*(gExportPBPtr->refNum), &gParaStart); /* position output pointer */
- gFirstTime = gNewParagraph = TRUE;
- gFirstStyle = TRUE;
- gPHeight = gNumFormats = gTextLength = 0;
- gRealParas = gNumParas = gParaLength = 0;
-
- gLineData = (LineHandle)NewHandle(0); /* Set up for storing line height info */
- if (*(gExportPBPtr->result) = MemError()) return(*(gExportPBPtr->result));
- gParaData = (ParagraphHandle)NewHandle(0); /* Set up for storing paragraph info */
- if (*(gExportPBPtr->result) = MemError()) return(*(gExportPBPtr->result));
- gFormatRun = (FormatHandle)NewHandle(0); /* Set up for storing format info */
- if (*(gExportPBPtr->result) = MemError()) return(*(gExportPBPtr->result));
-
- return(noErr);
- }
-
-
- /*----------------------------------------------------------------------*/
- /* */
- /* ChangeParagraph handles ruler changes in a paragraph. */
- /* */
- /*----------------------------------------------------------------------*/
- static Boolean ChangeParagraph()
- {
- register short i;
- register Boolean found_change;
-
- if (!(found_change = gFirstTime)) { /* Don't bother if this is the first time */
- if (*(gExportPBPtr->txtJust) != gOldJust)
- found_change = TRUE;
-
- if (!found_change) {
- for (i = 0; i < numParaFmts; i++) { /* Check for paragraph format change */
- if ((gExportPBPtr->paraFmts)[i] != gOldFmt[i]) {
- found_change = TRUE;
- break;
- }
- }
- if (!found_change) { /* Check for tab changes */
- for (i = 0; i < 10; i++) { /* Go forward to get all tabs */
- if ((gExportPBPtr->tabs)[i].tabJust != gOldTab[i].tabJust || (gExportPBPtr->tabs)[i].tabIndent != gOldTab[i].tabIndent)
- {
- if ((gExportPBPtr->tabs)[i].tabIndent != -1)
- found_change = TRUE;
- break;
- } else {
- if ((gExportPBPtr->tabs)[i].tabIndent == -1) /* Found end of tabs */
- break;
- }
- }
- }
- }
- }
-
- if (found_change) { /* Save the new changes for next time */
- gOldJust = *(gExportPBPtr->txtJust);
- for (i = 0; i < numParaFmts; i++)
- gOldFmt[i] = (gExportPBPtr->paraFmts)[i];
-
- for (i = 0; (i < 10) && ((gExportPBPtr->tabs)[i].tabIndent != -1); i++)
- gOldTab[i] = (gExportPBPtr->tabs)[i];
- }
- return(found_change);
- } /* ChangeParagraph */
-
-
- /*----------------------------------------------------------------------*/
- /* */
- /* InsertParagraph writes out current paragraph run. */
- /* */
- /*----------------------------------------------------------------------*/
- static short InsertParagraph()
- {
- short pad;
- register short format_length;
-
- GetEOF(*(gExportPBPtr->refNum), &gCount); /* Are we on an even word boundary */
- if (gCount & 1) { /* Write format run on even word boundary */
- pad = 0xFFFF;
- gCount = 1;
- if (*(gExportPBPtr->result) = FSWrite(*(gExportPBPtr->refNum), &gCount, &pad))
- return(*(gExportPBPtr->result));
- gParaLength++;
- }
- pad = format_length = GetHandleSize((Handle)gFormatRun);
-
- gCount = 2;
- if (*(gExportPBPtr->result) = FSWrite(*(gExportPBPtr->refNum), &gCount, &pad))
- return(*(gExportPBPtr->result));
-
- gCount = format_length;
- if (*(gExportPBPtr->result) = FSWrite(*(gExportPBPtr->refNum), &gCount, *gFormatRun))
- return(*(gExportPBPtr->result)); /* Write the run */
-
- SetHandleSize((Handle)gFormatRun, 0L); /* Reset for next run */
- gNumFormats = 0;
-
- gParaLength += 2; /* Room for format run length bytes */
-
- gNewParagraph = TRUE;
- SetHandleSize((Handle)gParaData, GetHandleSize((Handle)gParaData) + sizeof(ParagraphInfo));
- if (*(gExportPBPtr->result) = MemError()) return(*(gExportPBPtr->result));
-
- (*gParaData)[gNumParas].filePos = gParaStart; /* Where this paragraph started */
- (*gParaData)[gNumParas].ruler = FALSE; /* Not a ruler record */
- (*gParaData)[gNumParas].length = gParaLength; /* Text length bytes, text, pad byte, format run */
- (*gParaData)[gNumParas].justification = *(gExportPBPtr->txtJust);
- (*gParaData)[gNumParas].height = gPHeight;
-
- pad = 0;
- if (gNumParas) {
- pad = (*gParaData)[gNumParas - 1].height;
- if (pad < 0) pad = -pad; /* pictures have a negative height */
- pad += (*gParaData)[gNumParas - 1].pagePos;
- }
- if (pad < 0 || pad >= MWPageHeight)
- pad = 0;
- (*gParaData)[gNumParas].pagePos = pad;
- gNumParas++;
-
- SetHandleSize((Handle)gLineData, GetHandleSize((Handle)gLineData) + sizeof(LineInfo));
- if (*(gExportPBPtr->result) = MemError()) return(*(gExportPBPtr->result));
-
- (*gLineData)[gRealParas].nBytes = 1;
- (*gLineData)[gRealParas].lHeight = (gPHeight << 8) + gPHeight;
- gRealParas++;
- gPHeight = 0;
- if (*(gExportPBPtr->result) = SetFPos(*(gExportPBPtr->refNum), fsFromMark, -gParaLength))
- return(*(gExportPBPtr->result)); /* Move back to begining of text run */
-
- pad = gTextLength; /* Write text length in front of text run */
- gCount = 2;
- if (*(gExportPBPtr->result) = FSWrite(*(gExportPBPtr->refNum), &gCount, &pad))
- return(*(gExportPBPtr->result));
- if (*(gExportPBPtr->result) = SetFPos(*(gExportPBPtr->refNum), fsFromLEOF, 0L))
- return(*(gExportPBPtr->result)); /* Set back to end of file */
-
- gTextLength = 0;
- gParaLength = 0;
- GetEOF(*(gExportPBPtr->refNum), &gParaStart); /* For next paragraph */
-
- return(noErr);
- } /* InsertParagraph */
-
-
- /*----------------------------------------------------------------------*/
- /* */
- /* WritePict writes out a picture to MacWrite. */
- /* */
- /*----------------------------------------------------------------------*/
- static short WritePict()
- {
- register long picSize = GetHandleSize((Handle)(gExportPBPtr->thePicture));
- register short height, temp;
- Rect destRect;
-
- gTextLength--; /* Occurence of a floating pict character isn't gCounted in length */
-
- if (picSize > 0x7FFF) /* MacWrite can't handle pictures greater than 32K */
- return(0);
-
- if (gParaLength) {
- SetHandleSize((Handle)gFormatRun, 0L); /* Reset for next run */
- gNumFormats = 0;
- gParaLength = 0;
- gTextLength = 0;
- if (*(gExportPBPtr->result) = SetFPos(*(gExportPBPtr->refNum), fsFromStart, gParaStart))
- return(*(gExportPBPtr->result));
- }
- temp = 0;
-
- if (gNumParas) {
- temp = (*gParaData)[gNumParas - 1].height;
- if (temp < 0) temp = -temp; /* pictures have a negative height */
- temp += (*gParaData)[gNumParas - 1].pagePos;
- }
- if (temp < 0 || temp >= MWPageHeight)
- temp = 0;
-
- destRect = (gExportPBPtr->pictRect);
- height = destRect.bottom - destRect.top;
- OffsetRect(&destRect,
- -destRect.left + (FixRound((gExportPBPtr->paraFmts)[0] * 10 / 9) + 9),
- -destRect.top + temp);
-
- gCount = sizeof(Rect);
- if (*(gExportPBPtr->result) = FSWrite(*(gExportPBPtr->refNum), &gCount, &destRect))
- return(*(gExportPBPtr->result)); /* Write the destRect */
-
- HLock((Handle)(gExportPBPtr->thePicture));
- gCount = picSize;
- if (gCount & 1) gCount++;
-
- if (*(gExportPBPtr->result) = FSWrite(*(gExportPBPtr->refNum), &gCount, *(gExportPBPtr->thePicture)))
- return(*(gExportPBPtr->result)); /* Write the picture */
- HUnlock((Handle)(gExportPBPtr->thePicture));
- gCount += sizeof(Rect);
-
- SetHandleSize((Handle)gParaData, GetHandleSize((Handle)gParaData) + sizeof(ParagraphInfo));
- if (*(gExportPBPtr->result) = MemError()) return(*(gExportPBPtr->result));
-
- (*gParaData)[gNumParas].filePos = gParaStart; /* Where this paragraph started */
- (*gParaData)[gNumParas].ruler = TRUE; /* Is a ruler record */
- (*gParaData)[gNumParas].length = -gCount; /* Size of pict (-ve indicates pict) */
- (*gParaData)[gNumParas].justification = *(gExportPBPtr->txtJust);
- (*gParaData)[gNumParas].height = -height;
- (*gParaData)[gNumParas].pagePos = temp;
-
- gPHeight = 0;
- gNumParas++;
- SetHandleSize((Handle)gLineData, GetHandleSize((Handle)gLineData) + sizeof(LineInfo));
- if (*(gExportPBPtr->result) = MemError()) return(*(gExportPBPtr->result));
-
- (*gLineData)[gRealParas].nBytes = 0; /* picts have no line height */
- gRealParas++;
- if (*(gExportPBPtr->result) = SetFPos(*(gExportPBPtr->refNum), fsFromLEOF, 0L))
- return(*(gExportPBPtr->result)); /* Set back to end of file */
-
- gTextLength = 0;
- gParaLength = 0;
- gNewParagraph = TRUE;
- GetEOF(*(gExportPBPtr->refNum), &gParaStart); /* For next paragraph */
-
- return(noErr);
- } /* WritePict */
-
-
- /*----------------------------------------------------------------------*/
- /* */
- /* WritePageBreak writes out a page break to MacWrite. A page break */
- /* is a special picture paragraph, which has 'MAGICPIC' as the */
- /* coordinates of the quickdraw rectangle */
- /* */
- /*----------------------------------------------------------------------*/
- static short WritePageBreak()
- {
- Rect MAGICPIC;
- register PicHandle PH;
- register short height, temp;
- PictureParagraph PB;
-
- /*
- If there is a partial paragraph with real text in it, ie not just a format
- run - write it out.
- */
-
- gTextLength--; /* Occurrence of a page break character isn't gCounted in length */
- if (gParaLength > 2 + sizeof(FormatInfo))
- InsertParagraph();
- else {
- if (gParaLength) {
- SetHandleSize((Handle)gFormatRun, 0L); /* Reset for next run */
- gNumFormats = 0;
- gParaLength = 0;
- gTextLength = 0;
- if (*(gExportPBPtr->result) = SetFPos(*(gExportPBPtr->refNum), fsFromStart, gParaStart))
- return(*(gExportPBPtr->result));
- }
- }
- temp = 0;
-
- if (gNumParas) {
- temp = (*gParaData)[gNumParas - 1].height;
- if (temp < 0) temp = -temp; /* pictures have a negative height */
- temp += (*gParaData)[gNumParas - 1].pagePos;
- }
- if (temp < 0 || temp >= MWPageHeight)
- temp = 0;
-
- height = MWPageHeight - temp;
-
- /* Remember SetRect uses Left, Top, Right, Bottom */
- SetRect(&PB.pictureSize, 0xFFD6, 0, 0x3BE, height);
- MAGICPIC.top = 'MA';
- MAGICPIC.left = 'GI';
- MAGICPIC.bottom = 'CP';
- MAGICPIC.right = 'IC';
- PH = OpenPicture(&MAGICPIC);
- ClosePicture();
- HLock((Handle)PH);
-
- gCount = sizeof(Rect);
- if (*(gExportPBPtr->result) = FSWrite(*(gExportPBPtr->refNum), &gCount, &PB))
- return(*(gExportPBPtr->result)); /* Write the break */
-
- gCount = GetHandleSize((Handle)PH);
- if (gCount & 1) gCount++;
- if (*(gExportPBPtr->result) = FSWrite(*(gExportPBPtr->refNum), &gCount, *PH))
- return(*(gExportPBPtr->result)); /* Write the break */
-
- DisposHandle((Handle)PH);
-
- SetHandleSize((Handle)gParaData, GetHandleSize((Handle)gParaData) + sizeof(ParagraphInfo));
- if (*(gExportPBPtr->result) = MemError()) return(*(gExportPBPtr->result));
-
- (*gParaData)[gNumParas].pagePos = temp;
- (*gParaData)[gNumParas].filePos = gParaStart; /* Where this paragraph started */
- (*gParaData)[gNumParas].ruler = TRUE; /* Is a ruler record */
- (*gParaData)[gNumParas].length = -gCount - sizeof(Rect); /* Size of page break (- indicates pb) */
- (*gParaData)[gNumParas].justification = *(gExportPBPtr->txtJust);
- (*gParaData)[gNumParas].height = -height;
-
- gPHeight = 0;
- gNumParas++;
- SetHandleSize((Handle)gLineData, GetHandleSize((Handle)gLineData) + sizeof(LineInfo));
- if (*(gExportPBPtr->result) = MemError()) return(*(gExportPBPtr->result));
-
- (*gLineData)[gRealParas].nBytes = 0; /* picts have no line height */
- gRealParas++;
-
- if (*(gExportPBPtr->result) = SetFPos(*(gExportPBPtr->refNum), fsFromLEOF, 0L))
- return(*(gExportPBPtr->result)); /* Set back to end of file */
-
- gTextLength = 0;
- gParaLength = 0;
- gNewParagraph = TRUE;
- GetEOF(*(gExportPBPtr->refNum), &gParaStart); /* For next paragraph */
-
- return(noErr);
- } /* WritePageBreak */
-
-
- /*----------------------------------------------------------------------*/
- /* */
- /* InsertRuler */
- /* */
- /*----------------------------------------------------------------------*/
- static short InsertRuler()
-
- {
- #define RIGHTOFF 0x01FC /* Number of pixels of average right margin */
-
- register short i, pad, whichtab, tmptab;
- register RulerPtr buffer;
-
- SetHandleSize((Handle)gParaData, GetHandleSize((Handle)gParaData) + sizeof(ParagraphInfo));
- if (*(gExportPBPtr->result) = MemError()) return(*(gExportPBPtr->result));
-
- (*gParaData)[gNumParas].filePos = gParaStart;
- (*gParaData)[gNumParas].ruler = TRUE;
- (*gParaData)[gNumParas].length = sizeof(RulerInfo);
- (*gParaData)[gNumParas].justification = *(gExportPBPtr->txtJust);
- (*gParaData)[gNumParas].height = 0;
-
- pad = 0;
- if (gNumParas) {
- pad = (*gParaData)[gNumParas - 1].height;
- if (pad < 0)
- pad = -pad; /* pictures have a negative height */
- pad += (*gParaData)[gNumParas - 1].pagePos;
- }
-
- if (pad < 0 || pad >= MWPageHeight)
- pad = 0;
-
- (*gParaData)[gNumParas].pagePos = pad;
- gNumParas++;
-
- SetHandleSize((Handle)gLineData, GetHandleSize((Handle)gLineData) + sizeof(LineInfo));
- if (*(gExportPBPtr->result) = MemError()) return(*(gExportPBPtr->result));
-
- (*gLineData)[gRealParas].nBytes = 0; /* Rulers have no line height */
- gRealParas++;
-
- buffer = (RulerPtr) NewPtr(sizeof(RulerInfo));
-
- buffer->left = FixRound((gExportPBPtr->paraFmts)[0] / 9) * 9;
- buffer->right = gColumnWidth - FixRound((gExportPBPtr->paraFmts)[2] / 9) * 9;
- buffer->indentation = FixRound((gExportPBPtr->paraFmts)[1] / 9) * 9 + buffer->left;
- buffer->justification = *(gExportPBPtr->txtJust);
- if (buffer->right > RIGHTOFF)
- buffer->right = RIGHTOFF;
-
- /* figure out line spacing */
- if ((gExportPBPtr->paraFmts)[6] == -1) {
- if ((gExportPBPtr->paraFmts)[3] < 0x4000)
- buffer->spacing = 0;
- else {
- if ((gExportPBPtr->paraFmts)[3] < 0xC000)
- buffer->spacing = 1;
- else
- buffer->spacing = 2;
- }
- } else {
- if (HiWord((gExportPBPtr->paraFmts)[3]) < 15)
- buffer->spacing = 0;
- else {
- if (HiWord((gExportPBPtr->paraFmts)[3]) < 21)
- buffer->spacing = 1;
- else
- buffer->spacing = 2;
- }
- buffer->spacing |= 0x8000;
- }
- whichtab = 0;
- for (i = 0; (i < 10) && ((gExportPBPtr->tabs)[i].tabIndent != -1); i++) {
- tmptab = FixRound((gExportPBPtr->tabs)[i].tabIndent / 9) * 9;
-
- if (tmptab < buffer->left + 9) /* No tabs outside the margins */
- continue; /* or closer than 1/8 inch */
-
- if (tmptab > buffer->right - 9)
- break;
-
- if ((gExportPBPtr->tabs)[i].tabJust == textDecimal || (gExportPBPtr->tabs)[i].tabJust == textRight)
- tmptab = -tmptab;
-
- buffer->theTabs[whichtab++] = tmptab;
- }
- buffer->numTabs = whichtab;
- buffer->dummy = -1L;
-
- gCount = sizeof(RulerInfo);
- if (*(gExportPBPtr->result) = FSWrite(*(gExportPBPtr->refNum), &gCount, buffer))
- return(*(gExportPBPtr->result));
-
- DisposPtr((Ptr)buffer);
- GetEOF(*(gExportPBPtr->refNum), &gParaStart); /* Save for the next data sent */
-
- return(noErr);
- } /* InsertRuler */
-
-
- /*----------------------------------------------------------------------*/
- /* */
- /* FindFontSize determines if required font size is available */
- /* */
- /*----------------------------------------------------------------------*/
- static short FindFontSize(good_size)
- register short good_size;
- {
- register short i;
-
- /* Pin to largest or smallest value if appropriate */
- if (good_size >= MWSizes[MWFontSizes - 1]) return (MWSizes[MWFontSizes - 1]);
- if (good_size <= MWSizes[0]) return (MWSizes[0]);
-
- for (i = MWFontSizes - 1; i--;) {
- if (good_size == MWSizes[i]) return (MWSizes[i]); /* If exact, return */
-
- if (good_size > MWSizes[i]) { /* We are between valid MW sizes */
- if (MWSizes[i + 1] - good_size <= good_size - MWSizes[i])
- return (MWSizes[i + 1]);
- else
- return (MWSizes[i]);
- }
- }
- return(MWSizes[0]);
- } /* FindFontSize */
-
-
- /*----------------------------------------------------------------------*/
- /* */
- /* WriteParagraph handles output of current paragraph. */
- /* */
- /*----------------------------------------------------------------------*/
- static short WriteParagraph()
- {
- register unsigned char ch;
- register short theSize, i;
-
- unsigned char otherchar;
- short story;
- MacWriteWindow *wptr;
-
- SetHandleSize((Handle)gFormatRun, GetHandleSize((Handle)gFormatRun) + sizeof(FormatInfo));
- if (*(gExportPBPtr->result) = MemError()) return(*(gExportPBPtr->result));
-
- (*gFormatRun)[gNumFormats].filePos = gTextLength;
- theSize = FindFontSize(*(gExportPBPtr->txtSize) >> ((*(gExportPBPtr->txtFace) & textSuperior) ? 3 : 2));
-
- (*gFormatRun)[gNumFormats].pointSize = theSize;
- (*gFormatRun)[gNumFormats].styleSet = *(gExportPBPtr->txtFace) & StyleMask;
-
- if (*(gExportPBPtr->txtFace) & textSuperior) (*gFormatRun)[gNumFormats].styleSet |= textSuperScript;
- (*gFormatRun)[gNumFormats].fontNum = *(gExportPBPtr->txtFont);
-
- if (gFirstStyle) {
- switch(gExportPBPtr->currentStory)
- {
- case rightHeaderStory:
- case leftHeaderStory:
- case headerStory: story = AHeader;
- break;
-
- case rightFooterStory:
- case leftFooterStory:
- case footerStory: story = AFooter;
- break;
-
- case mainStory:
- default: story = TheMainDoc;
- break;
- }
-
- wptr = &(**MWHeader).window[story];
-
- wptr->activeStyle = theSize << 8;
- wptr->activeStyle |= *(gExportPBPtr->txtFace) & StyleMask;
- wptr->activeFont = *(gExportPBPtr->txtFont);
- gFirstStyle = FALSE;
- }
-
- gPHeight = ((theSize > gPHeight) ? theSize : gPHeight);
-
- gTextLength += *(gExportPBPtr->textLength);
- gNumFormats++;
- gParaLength += sizeof(FormatInfo);
-
- if (ChangeParagraph()) {
- if (*(gExportPBPtr->result) = InsertRuler())
- return(*(gExportPBPtr->result));
- gFirstTime = FALSE;
- }
- if (gNewParagraph) {
- gParaLength += 2;
- gCount = 2;
- if (*(gExportPBPtr->result) = FSWrite(*(gExportPBPtr->refNum), &gCount, *(gExportPBPtr->textBuffer)))
- return(*(gExportPBPtr->result));
- gNewParagraph = FALSE;
- }
- /* Output the text */
- for (i = 0; i < *(gExportPBPtr->textLength); i++) {
- if (gNewParagraph) {
- gParaLength += 2;
- gCount = 2;
- if (*(gExportPBPtr->result) = FSWrite(*(gExportPBPtr->refNum), &gCount, *(gExportPBPtr->textBuffer)))
- return(*(gExportPBPtr->result));
- gNewParagraph = FALSE;
- }
- ch = (*(gExportPBPtr->textBuffer) + i)[0];
- if (ISLINECHAR(ch) || ch == floatingPict) { /* Found end of a paragraph */
- switch (ch)
- {
- case newColumn:
- case newPage:
- case mergeBreak:
- /* Write the page break paragraph */
- *(gExportPBPtr->result) = WritePageBreak();
- break;
-
- case floatingPict:
- /*
- MacWrite 5.0 does not support floating pictures, so break the
- paragraph - write the picture, then start new paragraph
- */
-
- /* only insert a CR if this is not a new paragraph */
- if (gParaLength > 2 + sizeof(FormatInfo))
- if (*(gExportPBPtr->result) = WriteCR()) return(*(gExportPBPtr->result));
- *(gExportPBPtr->result) = WritePict();
- break;
-
- default:
- /* If it's any other kind of page breaker, just write a CR */
- *(gExportPBPtr->result) = WriteCR();
- break;
- }
- if (*(gExportPBPtr->result)) return(*(gExportPBPtr->result));
- } else {
- if (ch == softHyphen || ISSPECIALCHAR(ch))
- gTextLength--;
- else {
- otherchar = ch;
- gCount = 1;
- if (*(gExportPBPtr->result) = FSWrite(*(gExportPBPtr->refNum), &gCount, &otherchar))
- return(*(gExportPBPtr->result));
- gParaLength++;
- }
- }
- }
- return(noErr);
- } /* WriteParagraph */
-
-
- /*----------------------------------------------------------------------*/
- /* */
- /* WriteCR outputs a “carriage return” (0x0d). */
- /* */
- /*----------------------------------------------------------------------*/
- static short WriteCR()
- {
- unsigned char ch = 0x0D;
-
- gCount = 1;
-
- if (*(gExportPBPtr->result) = FSWrite(*(gExportPBPtr->refNum), &gCount, &ch))
- return *(gExportPBPtr->result);
-
- gParaLength++;
-
- if (*(gExportPBPtr->result) = InsertParagraph())
- return(*(gExportPBPtr->result));
-
- return(noErr);
- } /* WriteCR */
-
-
- /*----------------------------------------------------------------------*/
- /* */
- /* LastParagraph handles clean up after import is finished. */
- /* Called from CloseStory. */
- /* */
- /*----------------------------------------------------------------------*/
- static short LastParagraph()
- {
- /* Last paragraph is of zero bytes long. */
-
- if (gParaLength)
- if (*(gExportPBPtr->result) = InsertParagraph())
- return(*(gExportPBPtr->result));
-
- gParaLength += 2;
- gCount = 2;
- if (*(gExportPBPtr->result) = FSWrite(*(gExportPBPtr->refNum), &gCount, *(gExportPBPtr->textBuffer)))
- return(*(gExportPBPtr->result));
-
- gNewParagraph = FALSE;
- *(gExportPBPtr->textLength) = 0;
-
- if (*(gExportPBPtr->result) = WriteParagraph()) return(*(gExportPBPtr->result));
- if (*(gExportPBPtr->result) = InsertParagraph()) return(*(gExportPBPtr->result));
-
- return(noErr);
- } /* LastParagraph */
-
-
- /*----------------------------------------------------------------------*/
- /* */
- /* CloseStory handles ExportCloseMain directive. */
- /* */
- /*----------------------------------------------------------------------*/
- static short CloseStory()
- {
- register ParagraphPtr paraptr;
- register LinePtr LinePtr;
- register short i, story;
- InfoStruct InfoAry;
-
- if (*(gExportPBPtr->result) = LastParagraph()) return(*(gExportPBPtr->result));
-
- /* make sure that we do not exceed the max # of paras for headers & footers */
- if (gExportPBPtr->currentStory != mainStory && gNumParas - 1 >= MaxHFParas)
- {
- gNumParas = MaxHFParas;
- gRealParas = MaxHFParas - 1;
- }
-
- switch(gExportPBPtr->currentStory)
- {
- case rightHeaderStory:
- case leftHeaderStory:
- case headerStory:
- case rightFooterStory:
- case leftFooterStory:
- case footerStory:
- if (gExportPBPtr->currentStory == rightHeaderStory
- || gExportPBPtr->currentStory == leftHeaderStory
- || gExportPBPtr->currentStory == headerStory)
- {
- story = AHeader;
- (**MWHeader).headerPars = gNumParas;
- } else {
- story = AFooter;
- (**MWHeader).footerPars = gNumParas;
- }
- if (gExportPBPtr->pagePoint.v >= 0)
- (**MWHeader).window[story].pageNumPos = *(unsigned long *)&gExportPBPtr->pagePoint;
-
- if (gExportPBPtr->datePoint.v >= 0)
- (**MWHeader).window[story].datePos = *(unsigned long *)&gExportPBPtr->datePoint;
-
- if (gExportPBPtr->timePoint.v >= 0)
- (**MWHeader).window[story].timePos = *(unsigned long *)&gExportPBPtr->timePoint;
- break;
-
- case mainStory:
- story = TheMainDoc;
- (**MWHeader).mainPars = gNumParas;
- break;
- }
-
- /* Write line height array, store position & length */
- GetEOF(*(gExportPBPtr->refNum), &((**MWHeader).window[story].lineHeightAryPos));
- (**MWHeader).window[story].lineHeightAryLength = 0;
- HLock((Handle)gLineData);
- LinePtr = *gLineData;
-
- for (i = 0; (i <= gRealParas) && !(*(gExportPBPtr->result)); i++) {
- gCount = ((LinePtr->nBytes == 0) ? 2 : 4);
- (**MWHeader).window[story].lineHeightAryLength += gCount;
- *(gExportPBPtr->result) = FSWrite(*(gExportPBPtr->refNum), &gCount, LinePtr++);
- }
- if (*(gExportPBPtr->result)) return(*(gExportPBPtr->result));
- DisposHandle((Handle)gLineData);
-
- /* Write info array */
-
- /* First set up the common variables */
- InfoAry.paraHeight = InfoAry.paraPagePosn = InfoAry.paraFmt = 0;
- InfoAry.paraHndl = 0L; /* Handle used only by MacWrite internally */
-
- /* Now set up the info array pointer */
- GetEOF(*(gExportPBPtr->refNum), &(**MWHeader).window[story].infoAryPos);
- HLock((Handle)gParaData);
- paraptr = *gParaData;
- for (i = gNumParas; i-- && !(*(gExportPBPtr->result)); ) {
- InfoAry.paraHeight = paraptr->height;
- if (paraptr->length < 0)
- paraptr->length = -paraptr->length;
- InfoAry.Status.justCode = 0x00 /* (0x40 | paraptr->justification) */;
- InfoAry.Status.paraFilePosn = paraptr->filePos;
- InfoAry.paraLen = paraptr->length;
- InfoAry.paraPagePosn = paraptr->pagePos;
- gCount = 16;
- *(gExportPBPtr->result) = FSWrite(*(gExportPBPtr->refNum), &gCount, &InfoAry);
- paraptr++;
- }
- if (*(gExportPBPtr->result)) return(*(gExportPBPtr->result));
-
- DisposHandle((Handle)gParaData);
- DisposHandle((Handle)gFormatRun);
-
- (**MWHeader).window[story].infoAryLength = gNumParas << 4; /* gNumParas * 16 */
- return(noErr);
- } /* CloseStory */
-
-
- /*----------------------------------------------------------------------*/
- /* */
- /* TidyUp handles clean up after export is finished. */
- /* */
- /*----------------------------------------------------------------------*/
- static short TidyUp()
- {
- FreeBlock FreeList;
- ParamBlockRec paramblk;
- short vRef;
-
- /* Write Free List Array */
- GetEOF(*(gExportPBPtr->refNum), &(**MWHeader).freeListPos);
- FreeList.filePos = (**MWHeader).freeListPos + 8;
- GetVRefNum(*(gExportPBPtr->refNum), &vRef);
-
- paramblk.volumeParam.ioNamePtr = NULL;
- paramblk.volumeParam.ioVRefNum = vRef;
- paramblk.volumeParam.ioVolIndex = 0; /* Use only the vrefnum in search */
-
- PBGetVInfo(¶mblk, FALSE);
- FreeList.blockSize = (paramblk.volumeParam.ioVFrBlk * paramblk.volumeParam.ioVAlBlkSiz)
- - (**MWHeader).freeListPos + 8;
- (**MWHeader).freeListLen = (**MWHeader).freeListAlloc = gCount = 8;
-
- if (*(gExportPBPtr->result) = FSWrite(*(gExportPBPtr->refNum), &gCount, &FreeList))
- return(*(gExportPBPtr->result));
-
- SetFPos(*(gExportPBPtr->refNum), fsFromStart, 0L);
- gCount = sizeof(MacWriteHeader);
-
- if (*(gExportPBPtr->result) = FSWrite(*(gExportPBPtr->refNum), &gCount, *MWHeader))
- return(*(gExportPBPtr->result));
-
- DisposHandle((Handle)MWHeader);
- return(noErr);
- } /* TidyUp */
-